using System;
using System.Text;
using System.IO;
using System.Collections.Generic;
using Microsoft.Build.BuildEngine;

namespace PruneProj
{
    class Program
    {
        static int Main(string[] Args)
        {
            string fileContents;
            //Console.WriteLine("PruneProj Copyright (C) 2007, Telliam LLC.");

            if( Args.Length != 2 )
            {
                ShowUsage();
                return -1;
            }

            if( !File.Exists( Args[ 0 ] ) )
            {
                Console.Error.WriteLine( "File Not Found: {0}", Args[ 0 ] );
                return -1;
            }

            using(StreamReader infile = File.OpenText(Args[0]))
            {
                fileContents = infile.ReadToEnd();
            }

            if(fileContents.Contains("Microsoft Visual Studio Solution File"))
                ProcessSolutionFile(fileContents, Args[1]);
            else
                ProcessProjectFile(Args[0], Args[1]);
            
            return 0;
        }

        private static void ProcessSolutionFile(string FileContents, string OutPath)
        {
            string result = FileContents;
            int start = FileContents.IndexOf(@"GlobalSection(SourceCodeControl)");

            if(start >= 0)
            {
                int end = FileContents.IndexOf("EndGlobalSection", start) + 16;
                result = FileContents.Remove(start, end - start + 1);
            }

            using(StreamWriter outfile = File.CreateText(OutPath))
            {
                outfile.Write(result);
            }
        }

        private static void ProcessProjectFile(string ProjectPath, string OutPath)
        {
            Project proj = new Project();
            proj.Load(ProjectPath);

            StripVersionControlInfo(proj);

            TransformProjReferences(proj);

            proj.Save(OutPath);
        }

        private static void ShowUsage()
        {
            Console.WriteLine("Usage:");
            Console.WriteLine("PruneProj <SourceProj> <DestProj>");
        }

        /// <summary>Transform Project references into standard assembly references</summary>
        /// <param name="proj">Project to change</param>
        private static void TransformProjReferences(Project proj)
        {
            // list of names from ProjectReference Metadata
            List<string> newItems = new List<string>();

            // scan through all item groups
            foreach( BuildItemGroup itemGroup in proj.ItemGroups )
            {
                // keep a List of Project references found in this group
                // for later deletion. (e.g. don't alter the list while enumerating it!)
                List<BuildItem> removeItems = new List<BuildItem>();
                foreach( BuildItem item in itemGroup )
                {
                    if( item.Name == "ProjectReference" )
                    {
                        removeItems.Add(item);
                        newItems.Add(item.GetMetadata("Name"));
                    }
                }
                
                // delete the items found
                foreach( BuildItem item in removeItems )
                    itemGroup.RemoveItem(item);
            }

            // add in the new items as a reference
            foreach( string include in newItems )
                proj.AddNewItem("Reference", include);
        }

        /// <summary>Strips version control tags from the project</summary>
        /// <param name="proj">project to manipulate</param>
        private static void StripVersionControlInfo(Project proj)
        {
            // Iterate through each PropertyGroup in the Project.
            foreach( BuildPropertyGroup pg in proj.PropertyGroups )
            {
                List<BuildProperty> removeList = new List<BuildProperty>();

                // Iterate through each Property in the PropertyGroup.
                foreach( BuildProperty property in pg )
                {
                    if( property.Name.StartsWith("Scc") )
                        removeList.Add(property);
                }

                foreach( BuildProperty property in removeList )
                    pg.RemoveProperty(property);
            }
        }
    }
}
